package Day07;

import java.util.*;

/**
 * ---------------------------------------------------------------------------------------------------------
 * 题目：
 *      基因序列可以表示为一条由 8 个字符组成的字符串，其中每个字符都是 'A'、'C'、'G' 和 'T' 之一。
 *      假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。
 *      例如，"AACCGGTT" --> "AACCGGTA" 就是一次基因变化。
 *      另有一个基因库 bank 记录了所有有效的基因变化，只有基因库中的基因才是有效的基因序列。
 *      给你两个基因序列 start 和 end ，以及一个基因库 bank ，
 *      请你找出并返回能够使 start 变化为 end 所需的最少变化次数。如果无法完成此基因变化，返回 -1 。
 *      注意：起始基因序列 start 默认是有效的，但是它并不一定会出现在基因库中。
 * ---------------------------------------------------------------------------------------------------------
 * 示例：
 *      输入：start = "AACCGGTT", end = "AACCGGTA", bank = ["AACCGGTA"]
 *      输出：1
 * ---------------------------------------------------------------------------------------------------------
 * 方法：
 *      广度优先搜索
 * ---------------------------------------------------------------------------------------------------------
 */
class Solution {
    public static void main(String[] args) {
        String start = "AACCGGTT";
        String end = "AACCGGTA";
        String[] bank = new String[]{"AACCGGTA"};
        System.out.println(minMutation(start,end,bank));
    }
    public static int minMutation(String start, String end, String[] bank) {
        Queue<String> queue = new LinkedList<>();
        int step = 0;
        //找过的放在这里
        HashSet<String> book = new HashSet<>();
        //所有的放在这里
        HashSet<String> dict = new HashSet<>();
 
        //将给的单词全部加到dict里面去
        for(String s : bank){
            dict.add(s);
        }
 
        queue.offer(start);
        book.add(start);
 
        while(!queue.isEmpty()){
            int size = queue.size();
            while(size--!=0){
                String cur = queue.poll();
                //如果当前字符等于结尾字符那就说明找到了
                if(cur.equals(end)){
                    return step;
                }
                //修改单词的某一个字符
                for(int i=0;i<cur.length();++i){
                    StringBuffer s = new StringBuffer(cur);
                    for(char ch = 'A';ch<='Z';++ch){
                        s.setCharAt(i,ch);
                        //判断新的单词是不是在dict中，是不是不在book中
                        if(dict.contains(s.toString())&&!book.contains(s.toString())){
                            queue.offer(s.toString());
                            book.add(s.toString());
                        }
                    }
                }
            }
            step++;
        }
        return -1;
    }
}